package com.gjy.spring.b04;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;

import java.lang.reflect.Field;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-12-18 17:07:39
 */
public class B04 {

    public static void main(String[] args) throws NoSuchFieldException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(B04.class);
        context.registerBean("bean3", Bean3.class);
        ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
        resolver.setBeanFactory(context.getDefaultListableBeanFactory());

        // 获取@Value的内容
        //test1(context, resolver, Bean1.class.getDeclaredField("home"));
        //test2(context, resolver, Bean1.class.getDeclaredField("age"));
        test3(context, resolver, Bean2.class.getDeclaredField("bean3"));
//        test3(context, resolver, Bean4.class.getDeclaredField("value"));

    }

    private static void test3(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
        DependencyDescriptor descriptor = new DependencyDescriptor(field, false);
        String s = resolver.getSuggestedValue(descriptor).toString();
        System.out.println(s);

        String bean3 = context.getEnvironment().resolvePlaceholders(s); // 解析 ${}
        System.out.println("bean3 = " + bean3);

        Object o = context.getBeanFactory().getBeanExpressionResolver() // 解析 #{}
                .evaluate(bean3, new BeanExpressionContext(context.getBeanFactory(), null));

        Object res = context.getBeanFactory().getTypeConverter().convertIfNecessary(o, descriptor.getDependencyType());
        System.out.println(res);
        System.out.println(res.getClass());
    }

    private static void test2(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
        DependencyDescriptor descriptor = new DependencyDescriptor(field, false);
        String s = resolver.getSuggestedValue(descriptor).toString();
        System.out.println(s);

        String age = context.getEnvironment().resolvePlaceholders(s);
        System.out.println("age = " + age);
        System.out.println(age.getClass());

        Object o = context.getBeanFactory().getTypeConverter().convertIfNecessary(age, descriptor.getDependencyType());
        System.out.println("o = " + o);
        System.out.println(o.getClass());
    }

    private static void test1(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
        String s = resolver.getSuggestedValue(new DependencyDescriptor(field, false)).toString();
        System.out.println(s);

        String home = context.getEnvironment().resolvePlaceholders(s);
        System.out.println("home = " + home);
    }

    public class Bean1 {
        @Value("${JAVA_HOME}")
        private String home;
        @Value("18")
        private Integer age;
    }

    public class Bean2 {
        @Value("#{@bean3}") // SpringEL SpEL #{SpEL}
        private Bean3 bean3;
    }

    static class Bean3 {

    }

    static class Bean4 {
        @Value("#{'hello, '+'${JAVA_HOME}'}")
        private String value;
    }

}
